package edu.uaskl.jqf.model.gates;

import edu.uaskl.jqf.model.Complex;
import edu.uaskl.jqf.model.gates.util.BaseGate;
import edu.uaskl.jqf.model.matrix.MatrixComplex;
import edu.uaskl.jqf.model.matrix.MatrixComplexQuadraticIdentity;

public class ControlledU extends BaseGate {
    private static final MatrixComplex identity4 = MatrixComplexQuadraticIdentity.size4;
    private final MatrixComplex matrix;

    public ControlledU(final MatrixComplex matrix) {
        if ((matrix.getRows() != 2) || (matrix.getColumns() != 2))
            throw new IllegalArgumentException("Matrix size must be 2x2, got: " + matrix.getDimensionAsString());

        final Complex[][] values = new Complex[4][4];
        for (int i = 0; i < 4; i++) {
            values[0][i] = identity4.get(0, i);
            values[1][i] = identity4.get(1, i);
            if (i >= 2) {
                values[i][0] = identity4.get(i, 0);
                values[i][1] = identity4.get(i, 1);
            }
        }
        values[2][2] = matrix.get(0, 0);
        values[2][3] = matrix.get(0, 1);
        values[3][2] = matrix.get(1, 0);
        values[3][3] = matrix.get(1, 1);
        this.matrix = MatrixComplex.createMatrixBasedOnArray2d(values);
        if (!this.matrix.isUnitary())
            throw new IllegalStateException("Matrix is not unitary");
    }

    @Override
    public MatrixComplex getInstance() {
        return matrix;
    }

    @Override
    public MatrixComplex getSize(final int size) {
        if (size == 2)
            return getInstance();
        throw new IllegalArgumentException("Size not supported at the moment");
    }
}
